<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\command\ocean;

use app\command\BaseWork;
use app\enum\CommonEnum;
use app\enum\OeInvalidVideoEnum;
use app\model\OeInvalidVideoModel;
use app\model\OeInvalidVideoScheduleModel;
use app\service\client\AccountService;
use app\service\ocean\MaterialService;
use think\console\Input;
use think\console\Output;
use think\facade\Cache;

class InvalidVideoCleanupTaskAdvWork extends BaseWork
{
    public const SCHEDULE_ADV_LIST_KEY = 'schedule_oe_invalid_video_adv';

    protected function configure()
    {
        // 指令配置
        $this->setName('oe_invalid_video_cleanup_task_adv_work');
        // 设置参数
        $this->setDescription('定点执行清理巨量无效素材任务');
    }

    protected function execute(Input $input, Output $output)
    {
        set_time_limit(0);
        ini_set('memory_limit', '-1');
        $this->getOutputMessage('定点执行清理巨量无效素材任务开始');
        $redis = Cache::store('redis')->handler();
        $runTime = time() + 5 * 60;

        while (time() < $runTime) {
            $id = $redis->lpop(self::SCHEDULE_ADV_LIST_KEY);
            if (! $id) {
                sleep(rand(5, 10));
                continue;
            }

            $obj = (new OeInvalidVideoScheduleModel())->where('id', $id)->field(true)->find();
            if (! $obj instanceof OeInvalidVideoScheduleModel || ! $obj->getKey()) {
                continue;
            }

            $token = AccountService::getToken(CommonEnum::OE_MEDIA, $obj->getAttr('advertiser_id'));
            if (! $token) {
                $this->getOutputMessage('获取广告主账户[' . $obj->getAttr('advertiser_id') . ']token失败');
            }
            $headers = [
                'Access-Token' => $token,
                'Content-Type' => 'application/json',
            ];
            $materialIds = json_decode($obj->getAttr('material_id'), true);
            $data = [];
            foreach ($materialIds as $materialId) {
                $data[] = ['material_id' => intval($materialId), 'opt_status' => 'DISABLE'];
            }
            $params = [
                'advertiser_id' => intval($obj->getAttr('advertiser_id')),
                'promotion_id' => intval($obj->getAttr('promotion_id')),
                'data' => $data,
            ];

            $res = MaterialService::setPromotionVideoPause($headers, $params);
            if (! $res) {
                $this->getOutputMessage('任务[' . $id . ']关停失败:' . MaterialService::getError(0));
                // 如果是因项目不存在或已删除，则不重复处理
                if (MaterialService::getError(0) == '项目不存在或已删除' || MaterialService::getError(0) == '广告不存在或已删除') {
                    foreach ($data as $da) {
                        $content = (new OeInvalidVideoModel())->where([
                            'advertiser_id' => $obj->getAttr('advertiser_id'),
                            'material_id' => $da['material_id'],
                            'data_ym' => $obj->getAttr('data_ym'),
                        ])->field('id,step_adv_status')->find();
                        if ($content instanceof OeInvalidVideoModel && $content->getKey() && $content->getAttr('step_adv_status') == OeInvalidVideoEnum::CLOSE_STATUS_START) {
                            $content->setAttrs([
                                'step_adv_status' => OeInvalidVideoEnum::CLOSE_STATUS_FAIL,
                            ]);
                            if (! $content->save()) {
                                $this->getOutputMessage('material_id[' . $da['material_id'] . ']更新无效素材定点关停状态失败');
                            } else {
                                $this->getOutputMessage('material_id[' . $da['material_id'] . ']更新无效素材定点关停状态成功');
                            }
                        }
                    }
                } else {
                    // 其他错误，比如接口内部错误等，再重新执行
                    $redis->rPush(self::SCHEDULE_ADV_LIST_KEY, $id);
                    sleep(rand(5, 10));
                }
                continue;
            }
            // 关停成功的
            foreach ($res['data']['material_ids'] as $_materialId) {
                $content = (new OeInvalidVideoModel())->where([
                    'advertiser_id' => $obj->getAttr('advertiser_id'),
                    'material_id' => $_materialId,
                    'data_ym' => $obj->getAttr('data_ym'),
                ])->field('id,step_adv_status')->find();
                if ($content instanceof OeInvalidVideoModel && $content->getKey() && $content->getAttr('step_adv_status') == OeInvalidVideoEnum::CLOSE_STATUS_START) {
                    $content->setAttrs([
                        'step_adv_status' => OeInvalidVideoEnum::CLOSE_STATUS_SUCCESS,
                    ]);
                    if (! $content->save()) {
                        $this->getOutputMessage('任务[' . $id . ']更新无效素材定点关停状态失败');
                    }
                }
            }
            // 关停失败的
            foreach ($res['data']['errors'] as $err) {
                $content = (new OeInvalidVideoModel())->where([
                    'advertiser_id' => $obj->getAttr('advertiser_id'),
                    'material_id' => $err['material_id'],
                    'data_ym' => $obj->getAttr('data_ym'),
                ])->field('id,step_adv_status')->find();
                if ($content instanceof OeInvalidVideoModel && $content->getKey() && $content->getAttr('step_adv_status') == OeInvalidVideoEnum::CLOSE_STATUS_START) {
                    $content->setAttrs([
                        'step_adv_status' => OeInvalidVideoEnum::CLOSE_STATUS_FAIL,
                    ]);
                    if (! $content->save()) {
                        $this->getOutputMessage('任务[' . $id . ']更新无效素材定点关停状态失败');
                    }
                }
            }
            $this->getOutputMessage('任务[' . $id . ']定点关停完成');
        }

        $this->getOutputMessage('定点执行清理巨量无效素材任务结束');
    }
}
